#!/home/kuangxiaofeng/miniconda3/bin/python
# -*- coding: utf-8 -*-

from http.server import BaseHTTPRequestHandler, HTTPServer
from urllib.parse import urlparse
import json
import time as ttime
import BW_classification as bw
import IND_classification as ind
import pandas as pd
def whatstime():
    #####################################################
    # 			根据指定格式输出日期字符串 				#
    #	 							                    #
    #===================================================#
    # 参数说明：（无）                                  #
    #####################################################
    #  时间格式
    fmt = "[%Y-%b-%d  %H:%M:%S]: "
    timestr = ttime.strftime(fmt,ttime.localtime())
    return timestr

def predict_signiture_info(input_signiture_list):
    message = whatstime() + '正在预测签名黑白名单分类……'
    print(message)
    bw_classifier = bw.BW_Classifier()
    
    bw_regex_result = bw_classifier.regex_rule_predict(input_signiture_list)
    message = whatstime() + '正在做黑白名单的特征提取……'
    print(message)
    x_syn = bw_classifier.feature_extract(input_signiture_list)
    
    message = whatstime() + '正在做黑白名单的预测……'
    print(message)
    (bw_label_result,bw_label_result_proba) = bw_classifier.ml_predict(x_syn)
    
    #>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    # 正在预测签名行业分类
    message = whatstime() + '正在用强规则预测签名行业分类……'
    print(message)
    ind_classifier = ind.IND_Classifier()
    ind_regex_result = ind_classifier.regex_rule_predict(input_signiture_list)
    message = whatstime() + '正在做签名的特征提取……'
    print(message)    
    x_syn = ind_classifier.feature_extract(input_signiture_list)
    
    message = whatstime() + '正在做签名行业分类……'
    print(message)    
    (ind_label_result,ind_label_result_proba) = ind_classifier.ml_predict(x_syn)

    #>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    # 获取户部行业分类和对应id的字典
    ind_df = pd.read_csv('./Data/户部行业分类及ID对应表.csv',dtype={0:str,1:str})
    pub_type_code_map = {each.pub_type_code:each.pub_type for each in ind_df.itertuples()}
    # 待删 - 正式版要删掉 - head
    pub_type_code_map['机构组织-监督局'] = '015008'
	# 待删 - 正式版要删掉 - end
	#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
	# 整理一下结果准备输出
    output_object = list()
    for ii,each in enumerate(input_signiture_list):
        each_dict = dict()

        each_dict['signature'] = each
        each_dict['BW_regex_result'] = bw_regex_result[ii]
        each_dict['BW_ml_predict_result'] = bw_label_result[ii]
        each_dict['BW_ml_predict_proba'] = bw_label_result_proba[ii]
        each_dict['IND_regex_result'] = ind_regex_result[ii]
        try:
            each_dict['IND_regex_result_code'] = pub_type_code_map[ind_regex_result[ii]]
        except BaseException:
            each_dict['IND_regex_result_code'] = ''
        each_dict['IND_ml_predict_result_code'] = ind_label_result[ii]
        each_dict['IND_ml_predict_result'] = pub_type_code_map[ind_label_result[ii]]
        each_dict['IND_ml_predict_proba'] = ind_label_result_proba[ii]

        output_object.append(each_dict)

    output_str = json.dumps(output_object)
    return output_str

# HTTPRequestHandler class
class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
 
  # GET
  def do_GET(self):
    # Send response status code
    self.send_response(200)
     
    # Send headers
    self.send_header('Content-type','text/html')
    self.end_headers()
     
    # Send message back to client
    message = "Hello!This is CellPhone Robot."
    query = urlparse(self.path).path
    #query_components = dict(qc.split('=') for qc in query.split(''))
    query = query[1:].split('/')[0]
    print(query)
    # Write content as utf-8 data
    self.wfile.write(message.encode( "utf-8"))
    return
    
  def do_POST(self):
    # Send response status code
    # do post里面一定要加这三行代码，否则java的程序没法获取到返回的信息
    self.send_response(200)
    self.send_header('Content-type','text/html')
    self.end_headers()

    query = urlparse(self.path).path
    
    #para_dict = dict(qc.split('=') for qc in query.split('?'))
     
    content_length = int(self.headers['Content-Length'])
    post_data = self.rfile.read(content_length)
    resp = json.loads(post_data.decode('utf-8'))
    
    signiture_list = resp['signature']
    
    querys = query[1:].split('/')
    
    # 判断请求的长度，断定是查询预测还是模型训练
    if len(querys) == 1:
        # 查询预测
        action_mode = querys[0]
    elif len(querys) == 2:
        action_mode = querys[0]
        para_str = querys[1]
        try:
            paras = para_str.split('&')
            model_usage = paras[0].split('=')[-1]
            model_type = paras[1].split('=')[-1]
        except BaseException:
            raise ValueError('输入参数无效!请检查后重新发送')
    else:
        raise ValueError('输入参数无效!请检查后重新发送')

    if action_mode == 'predict':
        # 签名预测
        result_str = predict_signiture_info(signiture_list)
        #self.wfile.write(message.encode("utf-8"))
        self.wfile.write(result_str.encode("utf-8"))
        
    elif action_mode == 'train':
        #do train
        if model_usage == 'BW':
            # train BW classifier
            if model_type == 'mlp':
                # train mlp BW classifier
                print(whatstime() + '正在使用mlp训练黑白名单模型……')
            elif model_type == 'ensemble':
                # train mlp BW classifier
                print(whatstime() + '正在使用ensemble训练黑白名单模型……')                
            else:
                raise ValueError('输入参数无效!请检查后重新发送')
                
        elif model_usage == 'IND':
            # train IND classifier
            if model_type == 'mlp':
                # train mlp BW classifier
                print(whatstime() + '正在使用mlp训练行业分类模型……')
            elif model_type == 'ensemble':
                # train mlp BW classifier
                print(whatstime() + '正在使用ensemble训练行业分类模型……')                
            else:
                raise ValueError('输入参数无效!请检查后重新发送')
                
        else:
            raise ValueError('输入参数无效!请检查后重新发送')
    else:
        raise ValueError('输入参数无效!请检查后重新发送')    
        self.wfile.write('输入参数无效!请检查后重新发送'.encode("utf-8"))
    
    print(whatstime() + 'mission complete!')
    return

def run():
  print('starting server...')
 
  # Server settings
  # Choose port 8080, for port 80, which is normally used for a http server, you need root access
  port = 8081
  server_address = ('192.168.1.91', port)
  httpd = HTTPServer(server_address, testHTTPServer_RequestHandler)
  print('running server on port:%d...'%port)
  httpd.serve_forever()
 
if __name__  == '__main__':
    run()
